/*
 * StreetLightTests.java
 *
 * Created on Jun 3, 2007, 9:44:24 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.infomancers.workflow;

import com.infomancers.workflow.tests.*;
import com.infomancers.collections.actions.ValueSetterAction;
import com.infomancers.workflow.FlowManager;
import com.infomancers.workflow.concrete.ConcretePlace;
import com.infomancers.workflow.Transition;
import com.infomancers.workflow.dynamic.WorkflowBuilder;
import com.infomancers.workflow.managers.ConcurrentFlowManager;
import junit.framework.JUnit4TestAdapter;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author aviadbd
 */


public class StreetLightTests {
    
    public static junit.framework.Test suite() {
        return new JUnit4TestAdapter(StreetLightTests.class);
    }

    
    Workflow createWorkflow() {
        
        ConcretePlace red1 = new ConcretePlace("red1");
        ConcretePlace red2 = new ConcretePlace("red2");
        ConcretePlace green1 = new ConcretePlace("green1");
        ConcretePlace green2 = new ConcretePlace("green2");
        ConcretePlace control = new ConcretePlace("control");
        
        ConcretePlace input = new ConcretePlace("input");
        ConcretePlace output = new ConcretePlace("output");
        
        Transition rg1 = new Transition();
        Transition gr1 = new Transition();
        Transition rg2 = new Transition();
        Transition gr2 = new Transition();
        
        Transition switch1 = new Transition();
        Transition switch2 = new Transition();
        
        switch1.setPredicate(new PredicatedLight(1));
        switch2.setPredicate(new PredicatedLight(2));
        
        rg1.setAction(new ValueSetterAction<Object>("light", 1));
        rg2.setAction(new ValueSetterAction<Object>("light", 2));
        
        TestUtil.setEmptyPredicates(rg1, rg2, gr1, gr2);
        TestUtil.setEmptyActions(gr1, gr2, switch1, switch2);
        
        FlowManager manager = new ConcurrentFlowManager();
        
        WorkflowBuilder builder = new WorkflowBuilder();
        
        builder.addConnection(input, switch1);
        builder.addConnection(input, switch2);
        
        builder.addConnection(switch1, red1);
        builder.addConnection(switch1, control);

        builder.addConnection(switch2, red2);
        builder.addConnection(switch2, control);

        builder.addConnection(red1, rg1);
        builder.addConnection(control, rg1);
        
        builder.addConnection(red2, rg2);
        builder.addConnection(control, rg2);
        
        builder.addConnection(rg1, green1);
        builder.addConnection(rg2, green2);
        
        builder.addConnection(green1, gr1);
        builder.addConnection(green2, gr2);
        
        builder.addConnection(gr1, output);
        builder.addConnection(gr2, output);
        
        return builder.createWorkflow(input, output, manager);
    }
    
    private void runSwitch(Workflow workflow, int wanted) {
        WorkflowQueue queue = new WorkflowQueue(workflow);
        queue.pushData(new Light(wanted));
        
        Light result = (Light) queue.pullData();
        
        Assert.assertNotNull("No result returned", result);
        Assert.assertEquals("Wanted changed during process!", result.getWanted(), wanted);
        Assert.assertEquals("Light is not as wanted!", result.getLight(), result.getWanted());
    }
    
    @Test
    public void creation() {
        Assert.assertNotNull(createWorkflow());
    }
    
    @Test
    public void runGreen1() {
        runSwitch(createWorkflow(), 1);
    }
    
    @Test
    public void runGreen2() {
        runSwitch(createWorkflow(), 2);
    }
    
    @Test
    public void runColors() {
        Workflow wf = createWorkflow();
        runSwitch(wf, 1);
        runSwitch(wf, 2);
        runSwitch(wf, 1);
        runSwitch(wf, 2);
        runSwitch(wf, 1);
    }
}
